package com.kunya.order.common;

import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author zp
 * @Description:
 * @date 2018/7/12 14:14
 */
@Component
public class SingleRedissionLockTemplate implements RedissionLockTemplate{

    private static final Logger logger = LoggerFactory.getLogger(SingleRedissionLockTemplate.class);

    @Autowired
    private RedissionManager redissionManager;

    public SingleRedissionLockTemplate() {
    }



    // 尝试分布式重入锁
    @Override
    public <T> T tryLock(RedissionLockCallback<T> callback, long waitTime, long leaseTime, TimeUnit timeUnit, boolean fairLock) {
        boolean getLock = false;
        RLock lock = getLock(callback.getLockName(), fairLock);
        try {
            if (getLock = lock.tryLock(waitTime, leaseTime, timeUnit)) {
                logger.info("Redisson获取到分布式锁:{},ThreadName:{}", Thread.currentThread().getName());
                //返回为业务的返回值
                return callback.process();
            } else {
                logger.info("Redisson没有获取到分布式锁:{},ThreadName:{}", Thread.currentThread().getName());
            }
        } catch (InterruptedException e) {
            logger.info("Redisson分布式锁获取异常", e);
        } finally {
            //如果获取到分布式锁，关闭锁
            if(!getLock){
                return null;
            }
            lock.unlock();
            logger.info("Redisson分布式锁释放锁");

        }
        //没获取分布式锁返回null
        return null;
    }

    //fairLock为是否实现公平锁
    private RLock getLock(String lockName, boolean fairLock) {
        RLock lock;
        if (fairLock) {
            lock = redissionManager.getRedisson().getFairLock(lockName);
        } else {
            lock = redissionManager.getRedisson().getLock(lockName);
        }
        return lock;
    }

/*    public void setRedisson(Redisson redisson) {
        this.redisson = redisson;
    }*/
}
